package com.nl.controller.web.util;

import com.csvreader.CsvReader;
//import com.nl.controller.web.controller.SmsBaseStationController;
import com.nl.controller.xuyi.controller.XuYiOperatorController;
import com.nl.controller.web.bean.SmsBaseStation;
import com.nl.controller.web.global.GlobalConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
public class FileUtil {
    public static List readCSV(String path) {
        // 用来保存数据
        ArrayList<String> csvFileList = new ArrayList<String>();
        try {
            // 定义一个CSV路径
            String csvFilePath = path;
            // 创建CSV读对象 例如:CsvReader(文件路径，分隔符，编码格式);
            CsvReader reader = new CsvReader(csvFilePath, ',', Charset.forName("GBK"));
            // 跳过表头 如果需要表头的话，这句可以忽略
            reader.readHeaders();
            // 逐行读入除表头的数据
            while (reader.readRecord()) {
                System.out.println(reader.getRawRecord());
                csvFileList.add(reader.getRawRecord());
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return csvFileList;
    }


    public static List readCSV(InputStream inputStream) {
        // 用来保存数据
        ArrayList<String> csvFileList = new ArrayList<String>();
        try {

            // 创建CSV读对象 例如:CsvReader(文件路径，分隔符，编码格式);
            CsvReader reader = new CsvReader(inputStream, ',', Charset.forName("GBK"));
            // 跳过表头 如果需要表头的话，这句可以忽略
            reader.readHeaders();
            // 逐行读入除表头的数据
            while (reader.readRecord()) {
                System.out.println(reader.getRawRecord());
                csvFileList.add(reader.getRawRecord());
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return csvFileList;
    }

    /**
     * 文件下载
     *
     * @param fileName
     * @param res
     */
    public static void download(String fileName, HttpServletResponse res) {
        res.setCharacterEncoding("gbk");
        res.setContentType("multipart/form-data");
        res.addHeader("Content-Disposition", "attachment; fileName=" + fileName);
        InputStream is = null;
        OutputStream os = null;
        try {
            is = SmsBaseStation.class.getResourceAsStream("/model/" + fileName);
            os = res.getOutputStream();
            byte[] b = new byte[2048];
            int length;
            while ((length = is.read(b)) != -1) {
                if (fileName.indexOf("csv") > -1) {
                    os.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
                }

                os.write(b, 0, length);
            }
        } catch (Exception e) {
            log.info("文件下载异常,文件名：" + fileName);
            e.printStackTrace();
        } finally {
            try {
                os.close();
                is.close();
            } catch (IOException e) {
                log.info("文件下载关闭IO流异常···");
                e.printStackTrace();
            }
        }
        System.out.println("success");
    }

    public static void download(String fileName,String filePath, HttpServletResponse res) {
        res.setCharacterEncoding("gbk");
        res.setContentType("multipart/form-data");
        res.addHeader("Content-Disposition", "attachment; fileName=" + fileName);
        InputStream is = null;
        OutputStream os = null;
        try {
            is = SmsBaseStation.class.getResourceAsStream(filePath + fileName);
            os = res.getOutputStream();
            byte[] b = new byte[2048];
            int length;
            while ((length = is.read(b)) != -1) {
                if (fileName.indexOf("csv") > -1) {
                    os.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
                }

                os.write(b, 0, length);
            }
        } catch (Exception e) {
            log.info("文件下载异常,文件名：" + fileName);
            e.printStackTrace();
        } finally {
            try {
                os.close();
                is.close();
            } catch (IOException e) {
                log.info("文件下载关闭IO流异常···");
                e.printStackTrace();
            }
        }
        System.out.println("success");
    }


    /**
     * 文件下载
     *
     * @param fileName
     * @param res
     */
    public static void downloadOperator(String fileName, HttpServletResponse res) {
        res.setCharacterEncoding("GB2312");
        res.setContentType("multipart/form-data");
        res.addHeader("Content-Disposition", "attachment; fileName=" + fileName);
        InputStream is = null;
        OutputStream os = null;
        try {
            is = XuYiOperatorController.class.getResourceAsStream("/model/" + fileName);
            os = res.getOutputStream();
            byte[] b = new byte[2048];
            int length;
            while ((length = is.read(b)) != -1) {
                if (fileName.indexOf("csv") > -1) {
                    os.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
                }

                os.write(b, 0, length);
            }
        } catch (Exception e) {
            log.info("文件下载异常,文件名：" + fileName);
            e.printStackTrace();
        } finally {
            try {
                os.close();
                is.close();
            } catch (IOException e) {
                log.info("文件下载关闭IO流异常···");
                e.printStackTrace();
            }
        }
        System.out.println("success");
    }


    /**
     * 文件上传
     *
     * @param file
     * @param request
     * @param path
     * @param fileName
     * @return
     */
    public static String fileUpload(MultipartFile file,
                                    HttpServletRequest request,
                                    String path,
                                    String fileName) {
        if (!file.isEmpty()) {
            File filePath = new File(path, fileName);
            if (!filePath.getParentFile().exists()) {
                filePath.getParentFile().mkdirs();
            }
            try {
                file.transferTo(new File(path + File.separator + fileName));
                return "success";
            } catch (Exception e) {
                e.printStackTrace();
                log.error("文件上传出现异常");
                return "fail";
            }
        } else {
            return "文件为空";
        }
    }

    /**
     * 单文件复制
     *
     * @param oldPath
     * @param newPath
     */
    public void copyFile(String oldPath, String newPath) {
        try {
            int bytesum = 0;
            int byteread = 0;
            File oldfile = new File(oldPath);
            if (oldfile.exists()) { //文件存在时
                InputStream inStream = new FileInputStream(oldPath); //读入原文件
                FileOutputStream fs = new FileOutputStream(newPath);
                byte[] buffer = new byte[1444];
                int length;
                while ((byteread = inStream.read(buffer)) != -1) {
                    bytesum += byteread; //字节数 文件大小
                    System.out.println(bytesum);
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
            }
        } catch (Exception e) {
            System.out.println("复制单个文件操作出错");
            e.printStackTrace();

        }

    }

    //文件打包下载
    public static HttpServletResponse downLoadFiles(List<File> files,
                                                    HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        try {
            /**这个集合就是你想要打包的所有文件，
             * 这里假设已经准备好了所要打包的文件*/
            //List<File> files = new ArrayList<File>();

            /**创建一个临时压缩文件，
             * 我们会把文件流全部注入到这个文件中
             * 这里的文件你可以自定义是.rar还是.zip*/
            File file = new File(GlobalConst.TEMPPATH);
            if (!file.exists()) {
                file.createNewFile();
            }
            response.reset();
            //response.getWriter()
            //创建文件输出流
            FileOutputStream fous = new FileOutputStream(file);
            /**打包的方法我们会用到ZipOutputStream这样一个输出流,
             * 所以这里我们把输出流转换一下*/
            ZipOutputStream zipOut
                    = new ZipOutputStream(fous);
            /**这个方法接受的就是一个所要打包文件的集合，
             * 还有一个ZipOutputStream*/
            zipFile(files, zipOut);
            zipOut.close();
            fous.close();
            return downloadZip(file, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
        /**直到文件的打包已经成功了，
         * 文件的打包过程被我封装在FileUtil.zipFile这个静态方法中，
         * 稍后会呈现出来，接下来的就是往客户端写数据了*/
        return response;
    }

    /**
     * 把接受的全部文件打成压缩包
     *
     * @param
     * @param
     */
    public static void zipFile
    (List files, ZipOutputStream outputStream) {
        int size = files.size();
        for (int i = 0; i < size; i++) {
            File file = (File) files.get(i);
            zipFile(file, outputStream);
        }
    }

    /**
     * 文件下载
     * @param file
     * @param response
     * @return
     */
    public static HttpServletResponse downloadZip(File file, HttpServletResponse response) {
        try {
            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();

            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");

//如果输出的是中文名的文件，在此处就要用URLEncoder.encode方法进行处理
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                File f = new File(file.getPath());
                f.delete();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return response;
    }

    /**
     * 根据输入的文件与输出流对文件进行打包
     *
     * @param
     * @param
     */
    public static void zipFile(File inputFile,
                               ZipOutputStream ouputStream) {
        try {
            if (inputFile.exists()) {
                /**如果是目录的话这里是不采取操作的，
                 * 至于目录的打包正在研究中*/
                if (inputFile.isFile()) {
                    FileInputStream IN = new FileInputStream(inputFile);
                    BufferedInputStream bins = new BufferedInputStream(IN, 512);
                    //org.apache.tools.zip.ZipEntry
                    ZipEntry entry = new ZipEntry(inputFile.getName());
                    ouputStream.putNextEntry(entry);
                    // 向压缩文件中输出数据
                    int nNumber;
                    byte[] buffer = new byte[512];
                    while ((nNumber = bins.read(buffer)) != -1) {
                        ouputStream.write(buffer, 0, nNumber);
                    }
                    // 关闭创建的流对象
                    bins.close();
                    IN.close();
                } else {
                    try {
                        File[] files = inputFile.listFiles();
                        for (int i = 0; i < files.length; i++) {
                            zipFile(files[i], ouputStream);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
